{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "f(x[0]) = 7.25\n",
      "g0(x[0]) = 4.0 >= 0\n",
      "g1(x[0]) = 4.0 >= 0\n",
      "g2(x[0]) = 0.0 >= 0\n",
      "g3(x[0]) = 2.0 >= 0\n",
      "g4(x[0]) = 0.0 >= 0\n",
      "h0(x[0]) = 0.0 = 0\n",
      "------Begin testing------\n",
      "The equality constraint norm evaluated at x[6] is less than the global tolerance!\n",
      "------End testing------\n",
      "Time cost: 0.0410001277924[s]\n",
      "The optimal point is (1.40000363687, 1.70000273251)\n",
      "The minimum function value is 0.799998537507\n"
     ]
    },
    {
     "data": {
      "image/png": "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\nrHXW0W+4664LX3/d+Dl23RX69oWRI3O/lnnz4Lzz4Iwz9Fv5Rx9Bu3bx7bfeCl26wN57534u0M/w\nmWfC2Wfn53j5kO9rLCWrV+tn79BD4YUX4K67NG4zlWzfn1mz4Pnn4d57cyvnypUNe4jDqNT3ctEi\n2G8/OOggeO01eOstHQZ94QXo1Sv3NcF79oQWLXS0oH9/fU+fekrjfOvL5jOSr8+HqQ5hWoLldiOx\np05EZMiQeE/dWWdl2X42mRg7dmz6HRYvFhk3TqRPH/1WO2yYyDPPxLdfcYVIixYio0eLnHKKyE8/\n6fPz54t07CgyYEDd461eLXL00SI1NSJz5mR+jmbNRD79NLeLvfNOPe/bb+u38sTjzZsnstZaInPn\n5naO+pYtE9lgA5EpU359qtE6L5RCXWOpck5kr71EJE2dJ3l/klq5UmTPPUUeeyz3cl17rchTT+V2\njDJ4L0N/zi++WOSBBxo+P3KkvqfduyfvVctE8HnISiafkXx+PnJQtL8tVQzrqcuCTZYovjXW0F60\nQw/VgOy5c+GYY+LbDz9cg4LPPFPjUtq21ec7doTddoNRo+oezznYaqvsz7FqVe45C8eN02/offro\nt/KePePbbrtNVy5Ze+3czlFfixZa/rvuyu9xwyjUNZazTN+f886D88+HgQNzP+fKlbkH0lfye/nq\nq3DuufBkvfSmhxyivWuzZ8OECdGVJ5PPSD4/H6YqVGejbpdddKgOdHbXt98WtzwVKHGdxrRiQxOH\nHVb3+Q4d9Ofee2vjLFHHjvGA5HycY164idS/mjxZG3RNk2QIevRROPro3I6fiufp8FFtbfDQK8x5\nGlPIayxxaeu83vvTwLBh2qA4/HB9/Mwz8PPP+S5idsrgvQz9Od9sMx02//77us83bRr/W/DddzmV\nLWvpPiMl9Pko2t8Wk7VyzFOXu1atNKYqFk83diyccEJRi1T1Ntggu+fzeY4wcUjvvw+nn67/JL78\nUo+xww7agHziCdh0U3jvPY3vS5xxXV9tLdxwA3z1lcYJduyovSVPPqkxPytXakLlIUMavnbPPTWB\n9rRpGh9YDIW+xnKW7v158kn93Gy1lfYgicDLL2vsaLFU+nv57LPaaOvSpe7zS5fGv9httlm4Y4vA\nJ5/ozNYfftCRgy23hGuv1TjfVFJ9Rkrx82HKQnX21IGlNimwis9r1Lu3Blbfeqs+vukmfTx5sjbo\n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\nxpgxYzh6NHAc1wcffEC/fv04++yzadCgARdffDFLlizxK7Ny5UruvfdemjdvzrRp09gFUQz/AAAg\nAElEQVS+fTvXXnstVatWJTU1lenTp3vL3nPPPX5J4HXq1GH9+vXe4/369cPlclG2bFmmTp3q3b91\n61ZuuukmevXqRe3atWnXrh1vvOH/6/CHH37gqquuYujQoRw4cIDzzz+fGjVqMNcnEF61ahWXXnop\nrVu3pkmTJlx99dXs2rUraD9lZWXxxBNPcN5559GqVSvq1avHrbfeysGDBwE4ceIEs2bNYuDAgVSu\nXBmAjz/+mE6dOlGxYkV69erFzp07A86bnp7O6NGj6dSpE23atOGMM87gtddeCyh39OhR7r//fvr2\n7UvTpk1JTU3l3nvv5WQha0nfd999LFy4EGMMs2fPpnPnznTp0oUsn6u8CxYs4JJLLqFnz540atSI\nPn36MHv27ALP62vy5MkYY+jncJqmUO3atYsJEybw0ksv5VsmIyODxYsXA9CoUaOA46mpqQAsXboU\ngHnz5oVcNl5mzZrFgAED/PbNmzcPY0xI7d62bZt30Efe8ikpKdSvX5+srCxWrFjhd6xs2bJ06tSJ\n559/vtDPWYlQ0L1Z4K/AUaCzk3u7wFnYSYvjOniCBL93npDOOis3r+6DD8J+uebUFS7fz2Uoib+e\n700iPArjMJHZIysrSy644AK57LLLvPlAr732mhhj5OKLL/Yre//990uLFi1kx44dImJzdHr16iUp\nKSny3nvviYjIwYMH5euvv5bu3buLy+WSUaNGydChQ2XRokUyd+5cqVWrlpQrV0527tzpPe/MmTO9\nieV79+4NaGP37t3l448/9j7/8ccfpVu3brJp0yYRETl+/LhcddVVYoyRCRMmiIjILbfcIuXKlROX\nyyVDhgyR/v37S5UqVcTlcsn1118vIiLfffedVKxYUYYOHSoiIhkZGdKvXz+pXLmytG7dWs4++2x5\n+umnRUQkOztbLr30UnnzzTe97Zg+fbq4XC5p3769ZGRkyJo1a2Tu3LnicrnE5XLJxIkTZcKECbJy\n5UoZP368GGPkkksu8Xtv27Ztk6ZNm8qjjz7q3Tdo0CAxxvglrx89elR69OghX3zxhXffk08+KcYY\nufDCCwv4DlsLFy4UY4wMGTIk4Ngrr7widerUkR9//FFEbF7Y1VdfLcYYefzxxws9d0ZGhlStWlVq\n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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x8a10710>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# -*- coding: utf-8 -*-\n",
    "\"\"\"\n",
    "Copyright (C) Thu Jul 13 11:01:25 2017  Jianshan Zhou\n",
    "Contact: zhoujianshan@buaa.edu.cn\tjianshanzhou@foxmail.com\n",
    "Website: <https://github.com/JianshanZhou>\n",
    " \n",
    "This module implements the optimization algorithm based on the augmented Lagrangian\n",
    "multiplier method, in which some functions are coded by referring to \n",
    "the counterparts in the Scipy.optimize module.\n",
    "\"\"\"\n",
    "%matplotlib inline\n",
    "from __future__ import division, print_function, absolute_import\n",
    "\n",
    "\n",
    "import numpy as np\n",
    "from scipy.optimize import fmin_bfgs\n",
    "\n",
    "# some global constants\n",
    "_epsilon = np.sqrt(np.finfo(float).eps) # the float number accuracy\n",
    "# standard status messages of optimizers\n",
    "_status_message = {'success': 'Optimization terminated successfully.',\n",
    "                   'maxfev': 'Maximum number of function evaluations has '\n",
    "                              'been exceeded.',\n",
    "                   'maxiter': 'Maximum number of iterations has been '\n",
    "                              'exceeded.',\n",
    "                   'pr_loss': 'Desired error not necessarily achieved due '\n",
    "                              'to precision loss.'}\n",
    "\n",
    "# miscellaneous functions\n",
    "class OptimizeResult(dict):\n",
    "    \"\"\" Represents the optimization result.\n",
    "\n",
    "    Attributes\n",
    "    ----------\n",
    "    x : ndarray\n",
    "        The solution of the optimization.\n",
    "    success : bool\n",
    "        Whether or not the optimizer exited successfully.\n",
    "    status : int\n",
    "        Termination status of the optimizer. Its value depends on the\n",
    "        underlying solver. Refer to `message` for details.\n",
    "    message : str\n",
    "        Description of the cause of the termination.\n",
    "    fun, jac, hess: ndarray\n",
    "        Values of objective function, its Jacobian and its Hessian (if\n",
    "        available). The Hessians may be approximations, see the documentation\n",
    "        of the function in question.\n",
    "    hess_inv : object\n",
    "        Inverse of the objective function's Hessian; may be an approximation.\n",
    "        Not available for all solvers. The type of this attribute may be\n",
    "        either np.ndarray or scipy.sparse.linalg.LinearOperator.\n",
    "    nfev, njev, nhev : int\n",
    "        Number of evaluations of the objective functions and of its\n",
    "        Jacobian and Hessian.\n",
    "    nit : int\n",
    "        Number of iterations performed by the optimizer.\n",
    "    maxcv : float\n",
    "        The maximum constraint violation.\n",
    "\n",
    "    Notes\n",
    "    -----\n",
    "    There may be additional attributes not listed above depending of the\n",
    "    specific solver. Since this class is essentially a subclass of dict\n",
    "    with attribute accessors, one can see which attributes are available\n",
    "    using the `keys()` method.\n",
    "    \"\"\"\n",
    "    def __getattr__(self, name):\n",
    "        try:\n",
    "            return self[name]\n",
    "        except KeyError:\n",
    "            raise AttributeError(name)\n",
    "\n",
    "    __setattr__ = dict.__setitem__\n",
    "    __delattr__ = dict.__delitem__\n",
    "\n",
    "    def __repr__(self):\n",
    "        if self.keys():\n",
    "            m = max(map(len, list(self.keys()))) + 1\n",
    "            return '\\n'.join([k.rjust(m) + ': ' + repr(v)\n",
    "                              for k, v in sorted(self.items())])\n",
    "        else:\n",
    "            return self.__class__.__name__ + \"()\"\n",
    "\n",
    "    def __dir__(self):\n",
    "        return list(self.keys())\n",
    "\n",
    "\n",
    "def vecnorm(x, order = 2):\n",
    "    \"\"\"\n",
    "    Calculate the norm of a vector `x` given the norm order.\n",
    "    \"\"\"\n",
    "    if type(x) == np.ndarray:\n",
    "        if order == np.Inf:\n",
    "            return np.amax(np.abs(x))\n",
    "        elif order == -np.Inf:\n",
    "            return np.amin(np.abs(x))\n",
    "        else:\n",
    "            return np.sum(np.abs(x)**order, axis = 0)**(1.0/order)\n",
    "    else:\n",
    "        print(\"x is not a numpy ndarray!\")\n",
    "        exit(-1)\n",
    "\n",
    "\n",
    "def is_array_scalar(x):\n",
    "    \"\"\"\n",
    "    Check whether `x` is a scalar or an array scalar.\n",
    "    \"\"\"\n",
    "    return np.size(x) == 1\n",
    "\n",
    "\n",
    "def wrap_function(function, args):\n",
    "    ncalls = [0]\n",
    "    if function is None:\n",
    "        return ncalls, None\n",
    "\n",
    "    def function_wrapper(*wrapper_args):\n",
    "        ncalls[0] += 1 # record the number of times that the function is called.\n",
    "        return function(*(wrapper_args + args))\n",
    "\n",
    "    return ncalls, function_wrapper\n",
    "    \n",
    "\n",
    "# the main functions\n",
    "def ALMfunc(x, objFun, conFuns, w, v, sigma):\n",
    "    \"\"\"\n",
    "    The augmented Lagrangian function.\n",
    "    \n",
    "    Parameters\n",
    "    ----------\n",
    "    objFun : callable function objFun(x)\n",
    "        The objective function returns a scalar value.\n",
    "    conFuns : callable function conFuns(x)\n",
    "        The constraint function returns two arrays of the constraint values.\n",
    "    w : ndarray\n",
    "        The multipliers that correspond to the inequality constraints.\n",
    "    v : ndarray\n",
    "        The multipliers that correspond to the equality constraints.\n",
    "    sigma : float\n",
    "        The penalty factor.\n",
    "        \n",
    "    Returns\n",
    "    -------\n",
    "    augLagFun : scalar, a float\n",
    "        The value of the augmented Lagrangian function.\n",
    "    \"\"\"\n",
    "    ineqConFuns, eqConFuns = conFuns(x)\n",
    "    if (len(ineqConFuns) != len(w)) or (len(eqConFuns) != len(v)):\n",
    "        print(\"The multiplier number is not equal to that of the corresponding constraints!\")\n",
    "        exit(-1)\n",
    "    sumValue1 = np.sum([(np.max([0,wi-sigma*ineqi]))**2 - wi**2 for wi, ineqi in zip(w, ineqConFuns)])\n",
    "    sumValue2 = np.sum([0.5*sigma*((eqj)**2)-vj*eqj for vj, eqj in zip(v, eqConFuns)])\n",
    "    return objFun(x) + sumValue1/(2.*sigma) + sumValue2\n",
    "\n",
    "\n",
    "class _UnconstrainedOptimizationError(RuntimeError):\n",
    "    pass\n",
    "\n",
    "\n",
    "def fmin_ALM(objFun, x0, conFuns, eqConNum, ineqConNum, \\\n",
    "funArgs = (), conArgs = (), multiplierRange = (0.1, 1.0),\\\n",
    "gtol = 1e-5, sigma = 3.0, beta = 0.9, alpha = 1.3, \\\n",
    "norm = 2, epsilon = _epsilon, maxiter = None, full_output = 0, \\\n",
    "disp = 1, retall = 0, callback = None):\n",
    "    \"\"\"\n",
    "    The optimization algorithm application interface function.\n",
    "    \n",
    "    Returns\n",
    "    -------\n",
    "    xopt : ndarray\n",
    "        Parameters which minimize f, i.e. f(xopt) == fopt.\n",
    "    fopt : float\n",
    "        Minimum value.\n",
    "    func_calls : int\n",
    "        Number of function_calls made.\n",
    "    conFunc_calls : int\n",
    "        Number of conFunc_calls made.\n",
    "    warnflag : integer\n",
    "        0 : Success in the overall optimization.\n",
    "        1 : Maximum number of iterations exceeded.\n",
    "        2 : Failure in unconstrained optimization and/or function calls not changing.\n",
    "    success flag : bool\n",
    "        True : successfully solve the optimization problem.\n",
    "        False : otherwise\n",
    "    message : string\n",
    "        A description of the final optimization achievement.\n",
    "    allvecs  :  list\n",
    "        `OptimizeResult` at each iteration.  Only returned if retall is True.\n",
    "    \"\"\"\n",
    "    res = _fmin_ALM(objFun, x0, conFuns, eqConNum, ineqConNum, \\\n",
    "    funArgs, conArgs, multiplierRange,\\\n",
    "    gtol, sigma, beta, alpha, \\\n",
    "    norm, epsilon, maxiter, full_output, \\\n",
    "    disp, retall, callback)\n",
    "    # fun=fval, nfev=func_calls[0], nconev=conFunc_calls[0],\\\n",
    "    # status=warnflag, success=(warnflag == 0), message=msg,\\\n",
    "    # x=xk, nit=k\n",
    "    if full_output:\n",
    "        retlist = (res['x'], res['fun'],\\\n",
    "                   res['nfev'], res['nconev'], res['status'], res['message'],\\\n",
    "                   res['nit'])\n",
    "        if retall:\n",
    "            retlist += (res['allvecs'], )\n",
    "        return retlist\n",
    "    else:\n",
    "        if retall:\n",
    "            return res['x'], res['allvecs']\n",
    "        else:\n",
    "            return res['x']\n",
    "\n",
    "\n",
    "def _fmin_ALM(objFun, x0, conFuns, eqConNum, ineqConNum, \\\n",
    "funArgs = (), conArgs = (), multiplierRange = (0.1, 1.0),\\\n",
    "gtol = 1e-5, sigma = 3.0, beta = 0.9, alpha = 1.3, \\\n",
    "norm = 2, epsilon = _epsilon, maxiter = None, full_output = 0, \\\n",
    "disp = 1, retall = 0, callback = None):\n",
    "    \"\"\"\n",
    "    The main entrance function of the optimization algorithm based on the\n",
    "    augmented Lagrangian method.\n",
    "    \n",
    "    Parameters\n",
    "    ----------\n",
    "    objFun : callable objFun(x,*funArgs)\n",
    "        Objective function to be minimized.\n",
    "    x0 : ndarray\n",
    "        Initial guess.\n",
    "    conFuns : callable constraintFuns(x, *conArgs)\n",
    "        Constraint functions in which the equality and the inequality \n",
    "        constraints are defined, returning two lists of the constraints.\n",
    "    eqConNum : int\n",
    "        The number of the equality constraints.\n",
    "    ineqConNum : int\n",
    "        The number of the inequality constraints.\n",
    "    funArgs : tuple, optional\n",
    "        Extra arguments passed to objFun.\n",
    "    conArgs : tuple, optional\n",
    "        Extra arguments passed to conFuns.\n",
    "    multiplierRange : tuple, optional\n",
    "        The range of the initial multipliers.\n",
    "    gtol : float, optional\n",
    "        Equality constraint norm must be less than gtol before successful termination.\n",
    "    sigma : float, optional\n",
    "        Penalty factor.\n",
    "    beta : float, optional\n",
    "        Threshold to indicate the relative convergence speed.\n",
    "    alpha : float, optional\n",
    "        Coefficient rate to increase the penalty factor when it is necessary.\n",
    "    norm : float, optional\n",
    "        Order of norm (Inf is max, -Inf is min)\n",
    "    epsilon : int or ndarray, optional\n",
    "        If fprime is approximated, use this value for the step size.\n",
    "    callback : callable, optional\n",
    "        An optional user-supplied function to call after each\n",
    "        iteration.  Called as callback(xk), where xk is the\n",
    "        current parameter vector.\n",
    "    maxiter : int, optional\n",
    "        Maximum number of iterations to perform.\n",
    "    full_output : bool, optional\n",
    "        If True,return fopt, func_calls, and warnflag\n",
    "        in addition to xopt.\n",
    "    disp : bool, optional\n",
    "        Print convergence message if True.\n",
    "    retall : bool, optional\n",
    "        Return a list of results at each iteration if True.\n",
    "\n",
    "    Notes\n",
    "    -----\n",
    "    In each iteration of the optimization, the optimization problem is \n",
    "    transformed into an unconstrained optimization formulation, such that the\n",
    "    augmented Lagrangian objective function can be minimized by using \n",
    "    the quasi-Newton method of Broyden, Fletcher, Goldfarb, and Shanno (BFGS).\n",
    "    \"\"\"    \n",
    "    x0 = np.asarray(x0).flatten()\n",
    "    if x0.ndim == 0:\n",
    "        x0.shape = (1,)\n",
    "    if maxiter is None:\n",
    "        maxiter = len(x0)*200\n",
    "    opts = {'gtol':gtol, \n",
    "            'norm':norm,\n",
    "            'epsilon':epsilon, \n",
    "            'maxiter':maxiter, \n",
    "            'full_output':1, \n",
    "            'disp':0,\n",
    "            'retall':1, \n",
    "            'callback':None}\n",
    "            \n",
    "    func_calls, f = wrap_function(objFun, funArgs) # f is callable, i.e., f(x)\n",
    "    conFunc_calls, conF = wrap_function(conFuns, conArgs) # conf in each list returned by conF(x) is callable\n",
    "    allvecs = []\n",
    "    \n",
    "    gnorm = 1\n",
    "    fval = f(x0)\n",
    "    k = 0\n",
    "    if retall:\n",
    "        allvecs.append((x0, fval))\n",
    "    \n",
    "    # randomly initialize the multiplers corresponding to each constraint\n",
    "    # which is within [0.1,1.0]\n",
    "    if ineqConNum == 0:\n",
    "        wk = np.array([])\n",
    "    else:\n",
    "        wk = multiplierRange[0] + (multiplierRange[1] \\\n",
    "        - multiplierRange[0])*np.random.rand(ineqConNum)\n",
    "    if eqConNum == 0:\n",
    "        vk = np.array([])\n",
    "    else:\n",
    "        vk = multiplierRange[0] + (multiplierRange[1] \\\n",
    "        - multiplierRange[0])*np.random.rand(eqConNum)\n",
    "        \n",
    "    xk_1 = x0\n",
    "    warnflag = 0\n",
    "    if callback is not None:\n",
    "        callback(xk_1)\n",
    "    while (gnorm > gtol) and (k < maxiter):\n",
    "        # step 1:\n",
    "        # construct the augmented Lagrangian function\n",
    "        ALfun = lambda x : ALMfunc(x, f, conF, wk, vk, sigma)\n",
    "        \n",
    "        # step 2:\n",
    "        # Solve the unconstrained problem for x\n",
    "        try:\n",
    "            res = fmin_bfgs(ALfun, xk_1, fprime=None, args=(), **opts)\n",
    "            if disp:\n",
    "                print(\"The status of the %i-th unconstrained optimization: %s\"%(k, res[6]))\n",
    "        except _UnconstrainedOptimizationError:\n",
    "            warnflag = 2\n",
    "            break\n",
    "        \n",
    "        xk = res[0]\n",
    "        if callback is not None:\n",
    "            callback(xk)\n",
    "            \n",
    "        gnorm = vecnorm(conF(xk)[1], order=norm)\n",
    "        fval = f(xk)\n",
    "        # step 3:\n",
    "        # check whether the global tolerance is satisfied.\n",
    "        if gnorm < gtol:\n",
    "            print(\"\"\"The equality constraint norm evaluated at x[%i] is less than the global tolerance!\"\"\"%k)\n",
    "            break\n",
    "        # check the objective value\n",
    "        if not np.isfinite(fval):\n",
    "            print(\"\"\"The function value evaluated at x[%i] is infinite! Something may go wrong!\"\"\"%k)\n",
    "            warnflag = 2\n",
    "            break\n",
    "        if retall:\n",
    "            allvecs.append((xk, fval))\n",
    "            \n",
    "        # step 4:\n",
    "        # adapt the convergence speed.\n",
    "        den = vecnorm(conF(xk_1)[1], order=norm)\n",
    "        if (den != 0) and (gnorm/den >= beta):\n",
    "            # increase the penalty factor\n",
    "            sigma = alpha*sigma\n",
    "        \n",
    "        # step 5:\n",
    "        # Update the multipliers: wk and vk\n",
    "        _updateMultipliers(xk, wk, vk, sigma, conF)\n",
    "        k += 1\n",
    "        xk_1 = xk  \n",
    "        \n",
    "    if np.isnan(fval):\n",
    "        warnflag = 2\n",
    "        \n",
    "    if warnflag == 2:\n",
    "        msg = _status_message['pr_loss']\n",
    "        if disp:\n",
    "            print(\"Warning: \" + msg)\n",
    "            print(\"         Current function value: %f\" % fval)\n",
    "            print(\"         Iterations: %d\" % k)\n",
    "            print(\"         Function evaluations: %d\" % func_calls[0])\n",
    "            print(\"         Constraint evaluations: %d\" % conFunc_calls[0])\n",
    "    elif k >= maxiter:\n",
    "        warnflag = 1\n",
    "        msg = _status_message['maxiter']\n",
    "        if disp:\n",
    "            print(\"Warning: \" + msg)\n",
    "            print(\"         Current function value: %f\" % fval)\n",
    "            print(\"         Iterations: %d\" % k)\n",
    "            print(\"         Function evaluations: %d\" % func_calls[0])\n",
    "            print(\"         Constraint evaluations: %d\" % conFunc_calls[0])\n",
    "    else:\n",
    "        msg = _status_message['success']\n",
    "        if disp:\n",
    "            print(\"Warning: \" + msg)\n",
    "            print(\"         Current function value: %f\" % fval)\n",
    "            print(\"         Iterations: %d\" % k)\n",
    "            print(\"         Function evaluations: %d\" % func_calls[0])\n",
    "            print(\"         Constraint evaluations: %d\" % conFunc_calls[0])\n",
    "                \n",
    "    result = OptimizeResult(fun=fval, nfev=func_calls[0], nconev=conFunc_calls[0],\\\n",
    "                            status=warnflag, success=(warnflag == 0), message=msg,\\\n",
    "                            x=xk, nit=k)\n",
    "    if retall:\n",
    "        result['allvecs'] = allvecs\n",
    "    return result\n",
    "        \n",
    "        \n",
    "def _updateMultipliers(xk, wk, vk, sigma, conF):\n",
    "    ineqCons, eqCons = conF(xk)\n",
    "    i = 0\n",
    "    for wk_i, ineq_i in zip(wk, ineqCons):\n",
    "        wk[i] = np.max([0, wk_i-sigma*ineq_i])\n",
    "        i += 1\n",
    "    j = 0\n",
    "    for vk_j, eq_j in zip(vk, eqCons):\n",
    "        vk[j] = vk_j - sigma*eq_j\n",
    "        j += 1\n",
    "        \n",
    "        \n",
    "\"\"\"\n",
    "    Next, consider a minimization problem with several constraints for\n",
    "    testing the algorithm. The objective function is:\n",
    "\n",
    "    >>> fun = lambda x: (x[0] - 1)**2 + (x[1] - 2.5)**2\n",
    "\n",
    "    There are three constraints defined as:\n",
    "\n",
    "    >>> cons = ({'type': 'ineq', 'fun': lambda x:  x[0] - 2 * x[1] + 2},\n",
    "    ...         {'type': 'ineq', 'fun': lambda x: -x[0] - 2 * x[1] + 6},\n",
    "    ...         {'type': 'ineq', 'fun': lambda x: -x[0] + 2 * x[1] + 2},\n",
    "                {'type': 'eq',   'fun': lambda x: 1.7*x[0] + 0.6 * x[1] - 3.4})\n",
    "\n",
    "    And variables must be positive, hence the following bounds:\n",
    "\n",
    "    >>> bnds = ((0, None), (0, None))\n",
    "\n",
    "    The optimization problem is solved using the SLSQP method as:\n",
    "\n",
    "    >>> res = minimize(fun, (2, 0), method='SLSQP', bounds=bnds,\n",
    "    ...                constraints=cons)\n",
    "\n",
    "    It should converge to the theoretical solution (1.4 ,1.7).\n",
    "\"\"\"\n",
    "def testObjFun(x, parameters):\n",
    "    \"\"\"\n",
    "    The minimization objective function.\n",
    "    \n",
    "    Parameters\n",
    "    ----------\n",
    "    x : a list or a numpy array\n",
    "        The decision variables.\n",
    "    parameters : a list or a numpy array\n",
    "        The parameters passed to construct the objective function to be minimized.\n",
    "    Notes\n",
    "    -----\n",
    "    x and parameters need to be of the same size.\n",
    "    \"\"\"\n",
    "    return np.sum([(xi - parai)**2 for xi, parai in zip(x, parameters)])\n",
    "    \n",
    "def testConFun(x, parameters):\n",
    "    \"\"\"\n",
    "    The constraints.\n",
    "    \n",
    "    Parameters\n",
    "    ----------\n",
    "    x : a list or a numpy array\n",
    "        The decision variables.\n",
    "    parameters : a dict\n",
    "        The dictionary of the constraint conditions-related parameters, in which\n",
    "        the key is either the string 'ineq' or 'eq' and the value is a list of \n",
    "        tuples each containing the parameters passed to construct an inequality\n",
    "        or an equality constraint.\n",
    "    \"\"\"\n",
    "    ineqConsArray = []\n",
    "    eqConsArray = []\n",
    "    for keyStr, paraList in parameters.items():\n",
    "        if keyStr == 'ineq':\n",
    "            for paraTuple in paraList:\n",
    "                ineqConsArray.append(paraTuple[0]*x[0]+paraTuple[1]*x[1]+paraTuple[2])\n",
    "        elif keyStr == 'eq':\n",
    "            for paraTuple in paraList:\n",
    "                eqConsArray.append(paraTuple[0]*x[0]+paraTuple[1]*x[1]+paraTuple[2])\n",
    "        else:\n",
    "            print(\"The parameter dictionary of the constraints does not contain \\\n",
    "            the key '%s'!\"%keyStr)\n",
    "            exit(-1)\n",
    "    return np.asarray(ineqConsArray, dtype=np.float), np.asarray(eqConsArray, dtype=np.float)\n",
    "    \n",
    "if __name__ == \"__main__\":\n",
    "    import time\n",
    "    x0 = np.array([2, 0])\n",
    "    funParameters = np.array([1, 2.5])\n",
    "    ineqParameters = [(1, -2, 2), (-1, -2, 6), (-1, 2, 2), (1, 0, 0), (0, 1, 0)]\n",
    "    eqParameters = [(1.7, 0.6, -3.4)]\n",
    "    conParaDict = {'ineq':ineqParameters, 'eq':eqParameters}\n",
    "    # evaluate the function as well as the constraint functions at the initial point\n",
    "    fval0 = testObjFun(x0, funParameters)\n",
    "    ineqVals, eqVals = testConFun(x0, conParaDict)\n",
    "    print(\"f(x[0]) = %s\"%fval0)\n",
    "    for ineqIndex in range(len(ineqVals)):\n",
    "        print(\"g%i(x[0]) = %s >= 0\"%(ineqIndex, ineqVals[ineqIndex]))\n",
    "    for eqIndex in range(len(eqVals)):\n",
    "        print(\"h%i(x[0]) = %s = 0\"%(eqIndex, eqVals[eqIndex]))\n",
    "    \n",
    "    print(\"------Begin testing------\") \n",
    "    retall = 1\n",
    "    bt = time.time()\n",
    "    res = fmin_ALM(testObjFun, x0, testConFun, eqConNum = 1, ineqConNum = 5, \\\n",
    "    funArgs = (funParameters,), conArgs = (conParaDict,), multiplierRange = (0.1, 1.0),\\\n",
    "    gtol = 1e-5, sigma = 3.0, beta = 0.9, alpha = 1.3, \\\n",
    "    norm = 2, epsilon = _epsilon, maxiter = None, full_output = 1, \\\n",
    "    disp = 0, retall = retall, callback = None)\n",
    "    print(\"------End testing------\")\n",
    "    print(\"Time cost: %s[s]\"%(time.time()-bt))\n",
    "    print(\"The optimal point is (%s, %s)\"%(res[0][0], res[0][1]))\n",
    "    print(\"The minimum function value is %s\"%res[1])\n",
    "    if retall:\n",
    "        import matplotlib.pyplot as plt\n",
    "        plt.figure(0, figsize=(10,8))\n",
    "        plt.plot([xf[1] for xf in res[-1]], linewidth = 3.0, \\\n",
    "        color='red', marker='o', linestyle='-', \\\n",
    "        markersize = 20, fillstyle='none', \\\n",
    "        label = 'convergence to (%.3f,%.3f)'%(res[0][0],res[0][1]))\n",
    "        \n",
    "        plt.title('Ideal optimal point: (1.4,1.7)', fontsize=28, \\\n",
    "        fontname='Times New Roman', color='m')\n",
    "        plt.xlabel('Iteration', fontsize=28, fontname='Times New Roman')\n",
    "        plt.ylabel('Objective function value', fontsize=28, \\\n",
    "        fontname='Times New Roman')\n",
    "        \n",
    "        legendfont = {\"family\":\"Times New Roman\",\\\n",
    "              \"size\":23}        \n",
    "        plt.legend(prop=legendfont,bbox_to_anchor=(0.95,0.28))\n",
    "        plt.xticks(fontsize=23, fontname='serif')\n",
    "        plt.yticks(fontsize=23, fontname='serif')\n",
    "        problemStr = [\"$\\min_{(x_1,x_2)}{f(x)=(x_1-1)^2+(x_2-2.5)^2}$\",\\\n",
    "        \" $x_1 - 2x_2 + 2 \\geq0$\", \\\n",
    "        \" $-x_1 - 2x_2 + 6\\geq0$\", \\\n",
    "        \" $-x_1 + 2x_2 + 2\\geq0$\", \\\n",
    "        \" $1.7x_1 + 0.6x_2 - 3.4 = 0$\", \\\n",
    "        \" $x_1,x_2\\geq0$\"]  \n",
    "        vdist = 0.8\n",
    "        i = 0\n",
    "        for strLatex in problemStr[:-1]:            \n",
    "            plt.text(1, 6.6-vdist*i, strLatex, fontsize=23, color = 'red')\n",
    "            i += 1\n",
    "        plt.grid(True)       \n",
    "        plt.show()\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
